<script setup lang="ts">
import {ref} from 'vue';
import {dumpConfigJSON, loadConfigJSON} from "@/utils/config";
import SettingItem from "@/components/SettingItem.vue";
import {Download, Switch, Upload} from "@element-plus/icons-vue";
import {
  ImportBookmarkType,
  initBrowserError, Option,
  PageState,
  popupPageStatStoreKey
} from "@/utils/constants";
import moment from "moment";
import {genFileId, UploadInstance, UploadProps, UploadRawFile} from "element-plus";
import {Bookmark, dumpBookmarksJSON, loadBookmarksJSON, mergeBookmarks} from "@/utils/bookmarkUtils";
import {saveConfig} from "@/utils/componentUtils";
import {browserDriver, config} from "@/store/modules/globals";

const configJSONFile = ref<UploadInstance>()
const bookmarksJSONFile = ref<UploadInstance>()
const importBookmarkTypeArray: Option[] = Object.entries(ImportBookmarkType).map(
    ([key, value]) => (key !== "default" ? { "label": key , "value": value} : null)
).filter(item => !!item) as Option[];


/**
 * 备份配置
 */
function backupConfig() {
  const jsonData = dumpConfigJSON(config);
  console.log("jsonData", jsonData);
  const blob = new Blob([jsonData], { type: 'application/json' });
  const url = URL.createObjectURL(blob);
  // console.log("url", url);
  let filename: string = `config_${moment().valueOf().toString()}.json`
  const a = document.createElement('a');
  a.href = url;
  a.download = filename;
  a.style.display = 'none';
  document.body.appendChild(a);
  a.click();
  document.body.removeChild(a);
  URL.revokeObjectURL(url);
}

/**
 * 处理上传文件超出数量
 * @param files
 */
const handleConfigExceed: UploadProps['onExceed'] = (files) => {
  configJSONFile.value!.clearFiles();
  const file = files[0] as UploadRawFile;
  file.uid = genFileId();
  configJSONFile.value!.handleStart(file);
}

/**
 * 恢复配置
 * @param file
 * @param fileList
 */
function restoreConfig(file: any, fileList: any) {
  console.log("恢复配置", file, fileList);
  const reader = new FileReader();
  reader.onload = (e) => {
    if (!e.target) {
      console.log("e", e);
      return
    }
    let configJson = e.target.result;
    console.log('文件内容:', configJson);
    // 可以在这里对文件内容进行进一步处理，如解析文本、检查格式等
    if (!configJson) {
      return;
    }
    else if (typeof configJson === 'string') {

    } else {
      const decoder = new TextDecoder();
      configJson = decoder.decode(configJson);
    }
    if (!configJson) {
      return;
    }
    let newConfig = loadConfigJSON(configJson);
    config.fromConfig(newConfig);
  };
  reader.readAsText(file.raw);
}

/**
 * 备份收藏夹
 */
async function backupBookmarks() {
  if (!browserDriver.restoreStorageToObject) {
    throw initBrowserError
  }
  const pageState: PageState | null = await browserDriver.restoreStorageToObject(popupPageStatStoreKey);
  if (!pageState) {
    return false;
  }
  else if (!pageState.bookmark) {
    return false;
  }
  let bookmarksJSON = "";
  if (typeof pageState.bookmark == "string") {
    bookmarksJSON = pageState.bookmark;
  }
  else {
    bookmarksJSON = dumpBookmarksJSON(pageState.bookmark);
  }
  console.log("bookmarksJSON", bookmarksJSON);
  const blob = new Blob([bookmarksJSON], { type: 'application/json' });
  const url = URL.createObjectURL(blob);
  let filename: string = `bookmark_${moment().valueOf().toString()}.json`
  const a = document.createElement('a');
  a.href = url;
  a.download = filename;
  a.style.display = 'none';
  document.body.appendChild(a);
  a.click();
  document.body.removeChild(a);
  URL.revokeObjectURL(url);
}

/**
 * 处理上传文件超出数量
 * @param files
 */
const handleBookmarksExceed: UploadProps['onExceed'] = (files) => {
  bookmarksJSONFile.value!.clearFiles();
  const file = files[0] as UploadRawFile;
  file.uid = genFileId();
  bookmarksJSONFile.value!.handleStart(file);
}

/**
 * 恢复收藏夹
 * @param file
 * @param fileList
 */
function restoreBookmarks(file: any, fileList: any) {
  console.log("恢复配置", file, fileList);
  const reader = new FileReader();
  reader.onload = async (e) => {
    if (!e.target) {
      console.log("e", e);
      return
    }
    let bookmarksJson = e.target.result;
    console.log('文件内容:', bookmarksJson);
    // 可以在这里对文件内容进行进一步处理，如解析文本、检查格式等
    if (!bookmarksJson) {
      return;
    }
    else if (typeof bookmarksJson === 'string') {

    } else {
      const decoder = new TextDecoder();
      bookmarksJson = decoder.decode(bookmarksJson);
    }
    if (!browserDriver.restoreStorageToObject || !browserDriver.storeObjectToStorage) {
      throw initBrowserError;
    }
    let pageState: PageState | null = await browserDriver.restoreStorageToObject(popupPageStatStoreKey);
    if (!pageState || !pageState.bookmark) {
      const pageState: PageState = {
        bookmark: bookmarksJson,
        filterText: "",
        defaultExpandedKeys: [],
      };
      browserDriver.storeObjectToStorage(popupPageStatStoreKey, pageState);
    }
    else {
      if (config.importBookmarkType.value === ImportBookmarkType.merge) {
        let storeBookmarks: Bookmark[] = [];
        if (typeof pageState.bookmark === 'string') {
          storeBookmarks = loadBookmarksJSON(pageState.bookmark);
        }
        else if (Array.isArray(pageState.bookmark)) {
          // 如果是数组，进行相应的处理，比如将数组转换为合适的格式再传递给函数
          storeBookmarks = pageState.bookmark;
        }
        if (!storeBookmarks) {
          const msg = "存储的收藏夹数据有问题。";
          console.error(msg, pageState.bookmark);
          throw new Error(msg);
        }
        let bakBookmarks: Bookmark[] = loadBookmarksJSON(bookmarksJson);
        let finalBookmarks = mergeBookmarks(storeBookmarks, bakBookmarks);
        pageState.bookmark = dumpBookmarksJSON(finalBookmarks);
      }
      else {
        pageState.bookmark = bookmarksJson;
      }
      browserDriver.storeObjectToStorage(popupPageStatStoreKey, pageState);
    }
  };
  reader.readAsText(file.raw);
}

/**
 * 使用浏览器收藏夹
 */
function useBrowserBookmark() {
  if (!browserDriver.getBookmarkTree) {
    throw initBrowserError;
  }
  browserDriver.getBookmarkTree().then(async (bookmarkTree: Bookmark[]) => {
    if (!browserDriver.storeObjectToStorage || !browserDriver.restoreStorageToObject) {
      throw initBrowserError;
    }
    let bookmarksJson = dumpBookmarksJSON(bookmarkTree);
    let pageState: PageState | null = await browserDriver.restoreStorageToObject(popupPageStatStoreKey);
    if (!pageState || !pageState.bookmark) {
      pageState = {
        bookmark: bookmarksJson,
        filterText: "",
        defaultExpandedKeys: [],
      };
    }
    else {
      pageState.bookmark = bookmarksJson;
    }
    browserDriver.storeObjectToStorage(popupPageStatStoreKey, pageState);
  });

}

</script>

<template>
  <h2>收藏夹</h2>
  <setting-item
      name="导出收藏夹"
      description="导出收藏夹数据，其他浏览器可通过导入数据文件读取收藏夹数据"
  >
    <template #rightSlot>
      <el-button size="large" :icon="Download" @click="backupBookmarks">导出</el-button>
    </template>
  </setting-item>
  <setting-item
      name="导入收藏夹合并方法"
      description="导入收藏夹数据时，使用合并的方式导入还是使用覆盖的方式导入"
  >
    <template #rightSlot>
      <el-select
          v-model="config.importBookmarkType.value"
          size="large"
          style="width: 90px;"
          @change="saveConfig"
      >
        <el-option
            v-for="item in importBookmarkTypeArray"
            :key="item.value"
            :label="item.value"
            :value="item.value"
        />
      </el-select>
    </template>
  </setting-item>
  <setting-item
      name="导入收藏夹"
      description="导入本插件生成的收藏夹数据文件，可实现浏览器数据迁移功能，从其他浏览器迁移收藏夹数据"
  >
    <template #rightSlot>
      <el-upload
          ref="bookmarksJSONFile"
          :limit="1"
          accept=".json"
          :show-file-list="false"
          :on-exceed="handleBookmarksExceed"
          :auto-upload="false"
          :on-change="restoreBookmarks"
      >
        <el-button plain size="large" :icon="Upload">导入</el-button>
      </el-upload>
    </template>
  </setting-item>
  <setting-item
      name="使用浏览器书签"
      description="将插件中的收藏夹目录恢复成浏览器收藏夹的目录"
  >
    <template #rightSlot>
      <el-popconfirm
          confirm-button-text="确定"
          cancel-button-text="取消"
          title="是否使用浏览器书签？"
          hide-icon
          @confirm="useBrowserBookmark"
          @cancel=""
      >
        <template #reference>
          <el-button plain size="large" :icon="Switch">使用</el-button>
        </template>
      </el-popconfirm>
    </template>
  </setting-item>
  <h2>设置</h2>
  <setting-item
      name="导出设置"
      description="导出设置选项，方便多个浏览器之间同步设置。"
  >
    <template #rightSlot>
      <el-button plain size="large" :icon="Download" @click="backupConfig">导出</el-button>
    </template>
  </setting-item>
  <setting-item
      name="导入设置"
      description="导入设置项"
  >
    <template #rightSlot>
      <el-upload
          ref="configJSONFile"
          :limit="1"
          accept=".json"
          :show-file-list="false"
          :on-exceed="handleConfigExceed"
          :auto-upload="false"
          :on-change="restoreConfig"
      >
        <el-button plain size="large" :icon="Upload">导入</el-button>
      </el-upload>
    </template>
  </setting-item>
</template>

<style scoped>
h2 {
  user-select: none;
}
</style>

<style>
.el-popconfirm {
  user-select: none!important;
}
</style>